package com.zmn.oms.third.jingdong.service;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.jdwl.open.api.sdk.domain.lasim.ImServiceProviderExternalJsfSerivce.ImPendingOrderDto;
import com.jdwl.open.api.sdk.response.lasim.LasImHfsOrderSearchResponse;
import com.zmn.base.product.common.dto.product.ec.ProductBaseDRO;
import com.zmn.base.product.dubbo.interfaces.channel.product.third.ChannelProductThirdListRemoteService;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.constant.StatusConsts;
import com.zmn.common.dictionary.GlobalDict;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.oms.business.interfaces.baidumap.BaiduMapBService;
import com.zmn.oms.business.interfaces.notifylog.OrderNotifyLogBService;
import com.zmn.oms.business.interfaces.remark.OrderRemarkBService;
import com.zmn.oms.business.interfaces.third.JingDongServicePlusExtendService;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.model.bo.order.OrderBO;
import com.zmn.oms.model.dto.baidumap.LngLatLocation;
import com.zmn.oms.model.dto.order.proxy.CreateOrderDTO;
import com.zmn.oms.model.dto.product.OrderProductDTO;
import com.zmn.oms.model.entity.master.OrderMaster;
import com.zmn.oms.model.entity.notifylog.OrderNotifyLog;
import com.zmn.oms.model.entity.order.OrderExtend;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.entity.work.OrderWorkLogChange;
import com.zmn.oms.model.vo.remark.OrderRemarkDetailVO;
import com.zmn.oms.model.vo.remark.OrderRemarkVO;
import com.zmn.oms.model.vo.work.ZsOrderWorkVO;
import com.zmn.oms.services.interfaces.detail.OrderDetailService;
import com.zmn.oms.services.interfaces.master.OrderMasterService;
import com.zmn.oms.services.interfaces.order.OrderExtendService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.third.jingdong.JingdongApiInvoker;
import com.zmn.oms.third.jingdong.JingdongConsts;
import com.zmn.oms.third.jingdong.JingdongMapper;
import com.zmn.oms.third.jingdong.dto.api.*;
import com.zmn.oms.third.jingdong.handler.JdResponseHandler;
import com.zmn.oms.zmn.business.interfaces.proxy.ProxyOrderBService;
import com.zmn.oms.zmn.business.interfaces.work.ZsOrderWorkQueryBService;
import com.zmn.oms.zmn.business.interfaces.work.autoflow.WorkFlowContextBService;
import com.zmn.pay.common.constant.PayConsts;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 类描述：
 *
 * @author LiangHailong
 * @date 2019/09/07 15:31
 */
@Slf4j
@Service("jingdongService")
public class JingdongServiceImpl implements JingdongService {
    private static final Pattern OUTERID_PATTERN = Pattern.compile("\"serviceNo\"\\s*:\\s*(\\d+)");

    @Autowired
    private OrderMasterService orderMasterService;
    @Autowired
    private OrderRemarkBService orderRemarkBService;
    @Resource
    private OrderNotifyLogBService orderNotifyLogBService;
    @Autowired
    private OrderWorkService orderWorkService;
    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    private OrderExtendService orderExtendService;
    @Autowired
    private ProxyOrderBService proxyOrderBService;
    @Autowired
    protected ZsOrderWorkQueryBService zsOrderWorkQueryBService;
    @Autowired
    private WorkFlowContextBService workFlowContextBService;
    @Autowired
    private BaiduMapBService baiduMapBService;
    @Autowired
    private JingDongServicePlusExtendService jingDongServicePlusExtendService;

    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    protected ChannelProductThirdListRemoteService channelProductThirdListRemoteService;

    /**
     * 拉取订单
     */
    @Override
    public void pullOrder() {
        PullOrderResult result = JingdongApiInvoker.pullOrder();
        if (!result.isSuccess() || result.getJdOrderDTOs() == null) {
            return;
        }

        // 去除已入库的订单
        List<ImPendingOrderDto> jdOrderDTOs = filterDuplicate(result.getJdOrderDTOs());
        if (jdOrderDTOs.isEmpty()) {
            return;
        }

        List<CreateOrderDTO> zmnOrderDTOS = buildZmnOrders(jdOrderDTOs);
        if (zmnOrderDTOS.isEmpty()) {
            log.warn("【{}】录单失败：解析订单数据错误，ImPendingOrderDtos=[{}]", JingdongConsts.CHANNEL_NAME,
                    JSON.toJSONString(jdOrderDTOs));
            return;
        }

        // 保存订单
        for (CreateOrderDTO item : zmnOrderDTOS) {
            saveOrder(item);
        }
    }

    /**
     * 使用查询码拉取补偿订单
     */
    @Override
    public void pullOrderByQueryCode(String queryCode) {
        if (StringUtils.isBlank(queryCode)) {
            return;
        }

        PullOrderResult result = JingdongApiInvoker.pullOrderByQueryCode(queryCode);

        if (!result.isSuccess() || result.getJdOrderDTOs() == null) {
            return;
        }

        // 去除已入库的订单
        List<ImPendingOrderDto> jdOrderDTOs = filterDuplicate(result.getJdOrderDTOs());
        if (jdOrderDTOs.isEmpty()) {
            return;
        }

        List<CreateOrderDTO> zmnOrderDTOS = buildZmnOrders(jdOrderDTOs);
        if (zmnOrderDTOS.isEmpty()) {
            log.warn("【{}】录单失败：解析订单数据错误，ImPendingOrderDtos=[{}]", JingdongConsts.CHANNEL_NAME,
                    JSON.toJSONString(jdOrderDTOs));
            return;
        }

        // 保存订单
        for (CreateOrderDTO item : zmnOrderDTOS) {
            saveOrder(item);
        }
    }

    /**
     * 用于丢单时手动补偿录单
     * @param lasImHfsOrderSearchResponse
     */
    @Override
    public List<OrderBO> saveOrder4Remedy(LasImHfsOrderSearchResponse lasImHfsOrderSearchResponse)
            throws OmsBaseException {
        PullOrderResult result = JdResponseHandler.parsePullOrderResponse(lasImHfsOrderSearchResponse);
        if (!result.isSuccess() || result.getJdOrderDTOs() == null) {
            throw new OmsBaseException("数据有误！");
        }

        // 去除已入库的订单
        List<ImPendingOrderDto> jdOrderDTOs = filterDuplicate(result.getJdOrderDTOs());
        if (jdOrderDTOs.isEmpty()) {
            throw new OmsBaseException("订单已存在，不能重复录单！");
        }

        List<CreateOrderDTO> zmnOrderDTOS = buildZmnOrders(jdOrderDTOs);
        if (zmnOrderDTOS.isEmpty()) {
            throw new OmsBaseException("录单失败：解析订单数据错误！");
        }

        // 保存订单
        List<OrderBO> orderBOList = new LinkedList<>();
        for (CreateOrderDTO item : zmnOrderDTOS) {
            OrderBO orderBO = saveOrder(item);
            if (orderBO != null) {
                orderBOList.add(orderBO);
            }
        }

        return orderBOList;
    }

    /**
     * 同步预约时间
     * @param orderWorkLogChange
     */
    @Override
    public void syncDutyTime(OrderWorkLogChange orderWorkLogChange) {
        Long orderId = orderWorkLogChange.getOrderId();
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);
        OrderExtend orderExtend = orderExtendService.findMiniOrderExtendByOrderId(orderId);
        if (orderExtend == null) {
            log.warn("【{}】OrderExtend数据不存在！orderId=[{}]", JingdongConsts.CHANNEL_NAME, orderId);
        }

        OrderStatusParams params = new OrderStatusParams();
        params.setOrderId(orderId);
        params.setSyncType(OrderStatusParams.SYNC_TYPE_DUTY_TIME);
        params.setJdOrderId(getJdOrderId(orderWork, orderExtend));
        params.setServiceNos(getServiceNos(orderWork, orderExtend));

        // 预约时间
        Date dutyTime = Optional.ofNullable(orderWorkLogChange.getDutyTime()).orElse(orderWork.getDutyTime());
        if (dutyTime == null) {
            return;
        }
        Date dutyTimeEnd = DateUtil.addMinute(dutyTime, 60); // 一个小时
        params.setDutyTimeBegin(DateUtil.toString(dutyTime));
        params.setDutyTimeEnd(DateUtil.toString(dutyTimeEnd));
        // 是否首次预约
        params.setFirstFlag(isFirst(OrderStatusConsts.ORDER_STATUS_CONFIRM, orderId));

        SyncOrderResult result = JingdongApiInvoker.pushOrderStatus(params);

        saveSyncResult(orderWorkLogChange, OrderStatusConsts.ORDER_STATUS_CONFIRM, result);
    }

    /**
     * 同步工程师信息
     * @param orderWorkLogChange
     */
    @Override
    public void syncMaster(OrderWorkLogChange orderWorkLogChange) {
        Long orderId = orderWorkLogChange.getOrderId();
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);
        OrderExtend orderExtend = orderExtendService.findMiniOrderExtendByOrderId(orderId);
        if (orderExtend == null) {
            log.warn("【{}】OrderExtend数据不存在！orderId=[{}]", JingdongConsts.CHANNEL_NAME, orderId);
        }

        SyncOrderResult result = null;

        OrderStatusParams params = new OrderStatusParams();
        params.setOrderId(orderId);
        params.setSyncType(OrderStatusParams.SYNC_TYPE_MASTER);
        params.setJdOrderId(getJdOrderId(orderWork, orderExtend));
        params.setServiceNos(getServiceNos(orderWork, orderExtend));

        // 领单工程师
        List<OrderMaster> masterList = orderMasterService.listMasterByWorkId(orderWork.getOrderId(), orderWork.getWorkId());
        OrderMaster master = null;
        Integer masterId = orderWork.getMasterId();
        for (OrderMaster item : masterList) {
            if (item.getMasterId().equals(masterId)) {
                master = item;
                break;
            }
        }

        if (master == null) {
            log.info("【{}】同步工程师信息失败，没找到对应工程师。 orderId：[{}]，masterId：[{}]",
                    JingdongConsts.CHANNEL_NAME, orderId, masterId);

            result = new SyncOrderResult(false);
            result.setMsg(String.format("No Master found! masterId:[%d]", masterId));
        }
        else {
            /*
                屏蔽工程师的真实姓名，使用使用 工程师的姓+"工程师" 的格式进行同步 2021.11.11 by lhl
             */
            params.setMasterName(
                    Optional.ofNullable(master.getMasterName())
                            .filter(name -> name.length() >= 1)
                            .map(name -> String.format("%s工程师", name.substring(0,1)))
                            .orElse("工程师")
            );
            /*
                京东服务+ 侧用户下单后，有展现给工程师联系方式，因我司回传信息为空号手机导致用户大量投诉.
                为减少投诉，回传给京东服务+ 侧的电话，需能够联系到工程师或平台，规则如下：
                1. 工单绑定了隐私小号，向渠道方同步工程师电话为隐私小号；
                2. 工单未绑定隐私小号，向渠道方同步工程师电话为平台客服电话：4000806601；
                2021.11.09 by lhl
             */
            params.setMasterPhone(
                    Optional.ofNullable(orderDetailService.findOrderDetailByKey(orderId))
                            .map(orderDetail -> {
                                if (Objects.equals(orderDetail.getBindStatus(), OrderConsts.BIND_STATUS_BIND)
                                        && StringUtils.isNotBlank(orderDetail.getBindTelephone())) {
                                    return orderDetail.getBindTelephone();
                                }
                                return null;
                            })
                            .orElse(JingdongConsts.MASTER_PHONE)
            );
            // 是否首次指派工程师
            params.setFirstFlag(isFirst(OrderStatusConsts.ORDER_STATUS_DISTRIBUTE, orderId));

            result = JingdongApiInvoker.pushOrderStatus(params);
        }

        saveSyncResult(orderWorkLogChange, OrderStatusConsts.ORDER_STATUS_DISTRIBUTE, result);
    }

    /**
     * 同步订单完成
     * @param orderWorkLogChange
     */
    @Override
    public SyncOrderResult syncOrderComplete(OrderWorkLogChange orderWorkLogChange) {
        Long orderId = orderWorkLogChange.getOrderId();
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);
        OrderExtend orderExtend = orderExtendService.findMiniOrderExtendByOrderId(orderId);
        if (orderExtend == null) {
            log.warn("【{}】OrderExtend数据不存在！orderId=[{}]", JingdongConsts.CHANNEL_NAME, orderId);
        }

        OrderCompleteParams params = new OrderCompleteParams();
        params.setOrderId(orderId);
        params.setJdOrderId(getJdOrderId(orderWork, orderExtend));
        params.setServiceNos(getServiceNos(orderWork, orderExtend));
        params.setOperatorName(Optional.ofNullable(orderWorkLogChange.getOperatorName()).orElse("系统"));
        params.setOperatorTel(JingdongConsts.OPERATOR_PHONE);

        SyncOrderResult result = JingdongApiInvoker.pushOrderComplete(params);

        saveSyncResult(orderWorkLogChange, OrderStatusConsts.ORDER_STATUS_COMPLETE, result);

        return result;
    }



    /**
     * 同步订单取消
     * @param orderWorkLogChange
     */
    @Override
    public SyncOrderResult syncOrderCancel(OrderWorkLogChange orderWorkLogChange) {
        Long orderId = orderWorkLogChange.getOrderId();

        // 查询取消备注
        OrderRemarkVO orderRemarkVO = orderRemarkBService.findOrderRemarkVO(orderId, orderId, OrderConsts.ORDER_REMARK_TYPE_CANCEL);

        if (isScalping(orderRemarkVO)) {
            // 如果是刷单，执行刷单同步逻辑 2021-07-12 16:38:00 by lhl
            return syncOrderComplete4Scalping(orderWorkLogChange);
        }
        else {
            return syncOrderCancel(orderWorkLogChange, orderRemarkVO);
        }
    }

    /**
     * 判断是不是刷单
     * @param orderRemarkVO
     * @return
     */
    private boolean isScalping(OrderRemarkVO orderRemarkVO) {
        if (orderRemarkVO == null || orderRemarkVO.getDetailVOList() == null) {
            return false;
        }

        Integer scalpId = JingdongConsts.SCALP_ID;
        for (OrderRemarkDetailVO item : orderRemarkVO.getDetailVOList()) {
            if (Objects.equals(item.getMapId(), scalpId)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 刷单同步完成
     * @param orderWorkLogChange
     */
    private SyncOrderResult syncOrderComplete4Scalping(OrderWorkLogChange orderWorkLogChange) {
        SyncOrderResult result = syncOrderComplete(orderWorkLogChange);

        // 记录刷单数据
        if (result.isSuccess()) {
            try {
                jingDongServicePlusExtendService.saveOrderScalping(orderWorkLogChange.getOrderId());
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }

        return result;
    }

    /**
     * 取消订单
     * @param orderWorkLogChange
     * @param orderRemarkVO
     */
    private SyncOrderResult syncOrderCancel(OrderWorkLogChange orderWorkLogChange, OrderRemarkVO orderRemarkVO) {
        Long orderId = orderWorkLogChange.getOrderId();
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);
        OrderExtend orderExtend = orderExtendService.findMiniOrderExtendByOrderId(orderId);
        if (orderExtend == null) {
            log.warn("【{}】OrderExtend数据不存在！orderId=[{}]", JingdongConsts.CHANNEL_NAME, orderId);
        }

        OrderCancelParams params = new OrderCancelParams();
        params.setOrderId(orderId);
        params.setJdOrderId(getJdOrderId(orderWork, orderExtend));
        params.setServiceNos(getServiceNos(orderWork, orderExtend));
        params.setOperatorName(Optional.ofNullable(orderWorkLogChange.getOperatorName()).orElse("系统"));
        params.setOperatorTel(JingdongConsts.OPERATOR_PHONE);

        {// 取消备注（原因），需要将手写备注和选项备注进行拼接
            List<String> remarkList = new LinkedList<>();
            if (StringUtils.isNotBlank(orderRemarkVO.getContent())) {
                remarkList.add(orderRemarkVO.getContent());
            }
            if (orderRemarkVO.getDetailVOList() != null) {
                for (OrderRemarkDetailVO item : orderRemarkVO.getDetailVOList()) {
                    remarkList.add(item.getMapName());
                }
            }
            String remark = (remarkList.size() > 0) ? StringUtils.join(remarkList, "，") : null;
            params.setRemark(remark);
        }

        SyncOrderResult result = JingdongApiInvoker.pushOrderCancel(params);

        saveSyncResult(orderWorkLogChange, OrderStatusConsts.ORDER_STATUS_CANCEL, result);

        return result;
    }

    /**
     * 保存状态同步结果信息
     * @param orderWorkLogChange
     * @param orderStatus
     * @param result
     */
    private void saveSyncResult(OrderWorkLogChange orderWorkLogChange, int orderStatus, SyncOrderResult result) {
        if (result == null) {
            return;
        }

        OrderNotifyLog orderNotifyLog = new OrderNotifyLog();
        orderNotifyLog.setMqMsgKey(orderWorkLogChange.getMqMsgKey());
        orderNotifyLog.setOrderId(orderWorkLogChange.getOrderId());
        orderNotifyLog.setChannelId(orderWorkLogChange.getChannelId());
        orderNotifyLog.setOrderStatus(orderWorkLogChange.getStatus());
        orderNotifyLog.setOrderResultStatus(orderWorkLogChange.getResultStatus());
        orderNotifyLog.setNotifyStatus(String.valueOf(orderStatus));
        orderNotifyLog.setType(OrderConsts.ORDER_NOTIFY_TYPE_CHANGE);
        orderNotifyLog.setNotifyTime(DateUtil.getNow());
        orderNotifyLog.setNotifyResultMsg(String.format("[%s]-%s",
                OrderStatusConsts.getOrderStatusName(orderStatus), result.getMsg()));

        ResultDTO resultDTO = new ResultDTO();
        resultDTO.setStatus(result.isSuccess() ? StatusConsts.STATUS_SUCCESS : StatusConsts.STATUS_ERROR);
        resultDTO.setData(orderNotifyLog);

        orderNotifyLogBService.saveNotifyLog(resultDTO);
    }

    /**
     * 判断是不是首次同步预约/派工程师状态
     * @param orderStatus
     * @param orderId
     * @return
     */
    private boolean isFirst(int orderStatus, Long orderId) {
        List<OrderNotifyLog> orderNotifyLogs = orderNotifyLogBService.listByOrderId(orderId);
        if (orderNotifyLogs == null) {
            return true;
        }

        String statusStr = String.valueOf(orderStatus);
        for (OrderNotifyLog item : orderNotifyLogs) {
            if (statusStr.equals(item.getNotifyStatus()) && StatusConsts.STATUS_SUCCESS == item.getNotifyResultStatus()) {
                return false;
            }
        }

        return true;
    }

    /**
     * 获取服务单号
     * @param orderWork
     * @param orderExtend
     * @return
     */
    private String getJdOrderId(OrderWork orderWork, OrderExtend orderExtend) {
        // 2020-09-12号以后，将订单做了拆分，一个产品一个订单，不再将京东订单号作为外部订单号（outerId），改用
        // 京东服务单号作为外部订单号，京东订单号作为第二外部单号（orderExtend.extOuterId），
        // orderExtend.extOuterData中不再存储多个服务单号了
        if (StringUtils.isNotBlank(orderExtend.getExtOuterId())) {
            return orderExtend.getExtOuterId();
        }

        return orderWork.getOuterId();
    }

    /**
     * 获取服务单号
     * @param orderWork
     * @param orderExtend
     * @return
     */
    private List<Long> getServiceNos(OrderWork orderWork, OrderExtend orderExtend) {
        List<Long> serviceNos = new LinkedList<>();

        do {
            // 2020-09-12号以后，将订单做了拆分，一个产品一个订单，不再将京东订单号作为外部订单号（outerId），改用
            // 京东服务单号作为外部订单号，京东订单号作为第二外部单号（orderExtend.extOuterId），
            // orderExtend.extOuterData中不再存储多个服务单号了
            if (StringUtils.isNotBlank(orderExtend.getExtOuterId())) {
                serviceNos.add(Long.parseLong(orderWork.getOuterId()));
                break;
            }

            // 2019-11-06号以后，将ServiceNo保存在了orderExtend.extOuterData中
            if (orderExtend != null && StringUtils.isNotBlank(orderExtend.getExtOuterData())) {
                String[] arr = orderExtend.getExtOuterData().split(",");
                for (String item : arr) {
                    try {
                        serviceNos.add(Long.parseLong(item.trim()));
                    } catch (Exception e) {
                        log.error("【{}】ServiceNo转换错误： ServiceNo：[{}]，All_ServiceNos：[{}]",
                                JingdongConsts.CHANNEL_NAME, item, orderExtend.getExtOuterData());
                    }
                }
                break;
            }

            // 2019-11-06号以前，原始数据(orderExtend.outerData)中获取
            orderExtend = orderExtendService.findOrderExtendByOrderId(orderExtend.getExtId());
            ImPendingOrderDto jdOrder = JSON.parseObject(orderExtend.getOuterData(), ImPendingOrderDto.class);
            List<JingdongOrderDetail> jdOrderDetails = JSON.parseArray(jdOrder.getOrderDetail(), JingdongOrderDetail.class);
            for (JingdongOrderDetail item : jdOrderDetails) {
                serviceNos.add(item.getServiceNo());
            }
        } while (false);

        return serviceNos;
    }

    /**
     * 幂等校验去重
     * @param jdOrderDTOList
     * @return
     */
    private List<ImPendingOrderDto> filterDuplicate(List<ImPendingOrderDto> jdOrderDTOList) {
        List<ImPendingOrderDto> addList = new LinkedList<>();
        for (ImPendingOrderDto item : jdOrderDTOList) {
            String outerId = Optional.ofNullable(item.getOrderDetail())
                    .map(detailStr -> {
                        Matcher matcher = OUTERID_PATTERN.matcher(detailStr);
                        return matcher.find() ? matcher.group(1) : null;
                    })
                    .orElse(item.getOrderNo());
            ZsOrderWorkVO orderWork =
                    zsOrderWorkQueryBService.findOrderWorkByOuterId(outerId, JingdongConsts.CHANNEL_ID);
            if (orderWork == null) {
                addList.add(item);
            }
        }

        return addList;
    }

    /**
     * 保存订单
     * @param createOrderDTO
     */
    private OrderBO saveOrder(CreateOrderDTO createOrderDTO) {
        OrderBO orderBO = null;
        try {
            orderBO = proxyOrderBService.createOrder(createOrderDTO);
            OrderWork orderWork = orderBO.getOrderWork();
            log.info("【{}】保存订单成功。OrderWork:[{}]", JingdongConsts.CHANNEL_NAME,
                    JSON.toJSON(orderBO.getOrderWork()));

            // 工单自动流转
            workFlowContextBService.asyncAutoFlow(orderWork.getOrderId(),orderWork.getWorkId());
        } catch (Exception e) {
            log.info("【{}】保存订单失败。CreateOrderDTO:[{}]",
                    JingdongConsts.CHANNEL_NAME, JSON.toJSON(createOrderDTO));
            log.error(e.getMessage(), e);
        }
        return orderBO;
    }

    /**
     * 将京东订单转换成啄木鸟系统录单对象
     * @param jdOrderDTOs
     * @return
     */
    private List<CreateOrderDTO> buildZmnOrders(List<ImPendingOrderDto> jdOrderDTOs) {
        List<CreateOrderDTO> zmnOrders = new LinkedList<>();

        for (ImPendingOrderDto jdOrder : jdOrderDTOs) {
            log.info("【{}-订单】ImPendingOrderDto:[{}]",JingdongConsts.CHANNEL_NAME , JSON.toJSONString(jdOrder));

            CreateOrderDTO zmnOrder = _buildZmnOrderWithoutProductInfo(jdOrder);
            if (zmnOrder == null) {
                continue;
            }

            List<JingdongOrderDetail> jdOrderDetails = JSON.parseArray(jdOrder.getOrderDetail(), JingdongOrderDetail.class);
            for (int i=0, len=jdOrderDetails.size()-1; i<=len; i++) {
                JingdongOrderDetail jdOrderDetail = jdOrderDetails.get(i);
                CreateOrderDTO zmnOrderCopy = null;
                if (i == len) {
                    // 最后一个订单，不需要再创建订单副本对象，使用原对象即可
                    zmnOrderCopy = zmnOrder;
                }
                else {
                    zmnOrderCopy = new CreateOrderDTO();
                    BeanMapper.copy(zmnOrder, zmnOrderCopy);
                }

                try {
                    _fillProduct(zmnOrderCopy, jdOrderDetail);
                } catch (Exception e) {
                    log.error("【{}-消息-订单】ErrorMsg:[{}]", JingdongConsts.CHANNEL_NAME, e.getMessage(), e);
                    continue;
                }

                zmnOrderCopy.setOuterId(String.valueOf(jdOrderDetail.getServiceNo()));
                jdOrder.setOrderDetail(JSON.toJSONString(Lists.newArrayList(jdOrderDetail)));
                zmnOrderCopy.setOuterData(JSON.toJSONString(jdOrder));

                zmnOrders.add(zmnOrderCopy);
            }
        }

        return zmnOrders;
    }

    /**
     * 将京东订单转换成啄木鸟系统录单对象
     * @param jdOrder
     * @return
     */
    private CreateOrderDTO _buildZmnOrderWithoutProductInfo(ImPendingOrderDto jdOrder) {
        CreateOrderDTO zmnOrder = new CreateOrderDTO();

        zmnOrder.setContactName(jdOrder.getCustomerName()); // 用户-订单用户
        zmnOrder.setTelephone(jdOrder.getCustomerTel());
        zmnOrder.setExtOuterId(jdOrder.getOrderNo());

        // expectAtHomeDate 用户期望上门日期（预约时间），注意就近转化为：整点和半点
        String expectDate = jdOrder.getExpectAtHomeDate();
        if (StringUtils.isNotBlank(expectDate)) {
            Date dutyTime = DateUtil.parse(expectDate, DateUtil.FORMAT_DEFAULT);
            // 忽略掉当前时间超过预约时间的情况，由线下去确定预约时间
            if (dutyTime.getTime() > System.currentTimeMillis()) {
                zmnOrder.setDutyTime(DateUtil.round(dutyTime, DateUtil.UNIT_MINUTE));
            }
        }

        try {
            _fillAddress(zmnOrder, jdOrder);
        } catch (Exception e) {
            log.error("【{}-消息-订单】ErrorMsg:[{}]", JingdongConsts.CHANNEL_NAME, e.getMessage(), e);
            return null;
        }

        zmnOrder.setPlat(GlobalConsts.PLAT_MARK_ZMN);
        zmnOrder.setChannelId(JingdongConsts.CHANNEL_ID);
        zmnOrder.setGender(GlobalDict.GENDER_NO);
        zmnOrder.setDisableDiscard(GlobalConsts.NO);
        zmnOrder.setOperator("系统");
        zmnOrder.setOperatorId((long) GlobalConsts.OPERATE_USER_TYPE_SYSTEM);
        zmnOrder.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_CHANNEL);
        zmnOrder.setInputType(OrderConsts.ORDER_INPUT_TYPE_API);

        return zmnOrder;
    }

    /**
     * 补全订单地址：将京东订单地址转换成符合我们自己系统使用的地址信息
     * @param zmnOrder
     * @param jdOrder
     */
    private void _fillAddress(CreateOrderDTO zmnOrder, ImPendingOrderDto jdOrder) {
        StringBuilder addressSb = new StringBuilder();
        addressSb.append(Optional.ofNullable(jdOrder.getReceiveProvinceName()).orElse("").trim())
                .append(Optional.ofNullable(jdOrder.getReceiveCityName()).orElse("").trim())
                .append(Optional.ofNullable(jdOrder.getReceiveDistrictName()).orElse("").trim())
                .append(Optional.ofNullable(jdOrder.getReceiveTownName()).orElse("").trim());

        String address = addressSb.toString();
        String street = jdOrder.getCustomerAddress().replace(address, "").trim();

        zmnOrder.setAddress(address);
        zmnOrder.setStreet(street); // street字段在数据库中不能为空

        String addressStr = null;
        addressStr = address + street;
        addressStr = addressStr.replaceAll(" ", "");
        try {
            LngLatLocation location = baiduMapBService.location(addressStr);
            if (location != null) {
                zmnOrder.setLatitude(Double.valueOf(location.getLat()));
                zmnOrder.setLongitude(Double.valueOf(location.getLng()));
            }
            else {
                zmnOrder.setCityId(500100); // 默认重庆
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);

            if(zmnOrder.getCityId() == null) {
                zmnOrder.setCityId(500100); // 默认重庆
            }
        }

        // 记录一下完整地址
        zmnOrder.setOperatorLogRemark(addressStr);
    }

    /**
     * 补全产品信息
     * @param zmnOrder
     * @param jdOrderDetail
     */
    private void _fillProduct(CreateOrderDTO zmnOrder, JingdongOrderDetail jdOrderDetail) {
        Integer num = Optional.ofNullable(jdOrderDetail.getGoodsCount()).orElse(1);

        OrderProductDTO orderProduct = new OrderProductDTO();

        // 产品ID
        ResponseDTO<List<ProductBaseDRO>> servProductListResponseDTO =
                channelProductThirdListRemoteService.listByChannelIdAndProductParentIdAndSubId(JingdongConsts.CHANNEL_ID,
                        jdOrderDetail.getGoodsNo(),null);
        log.info("【{}】 #ChannelProductMapListRemoteService#listByChannelIdAndProductParentIdAndProductSubId# 入参【{}】【{}】，出参【{}】",
                JingdongConsts.CHANNEL_NAME, JingdongConsts.CHANNEL_ID, jdOrderDetail.getGoodsNo(),
                servProductListResponseDTO.toString());
        if (!servProductListResponseDTO.isSuccess() || Objects.isNull(servProductListResponseDTO.getData()) ||
                servProductListResponseDTO.getData().isEmpty()) {
            orderProduct.setProductId(
                    JingdongMapper.getZmnProductId(null, jdOrderDetail.getGoodsNo(), GlobalConsts.SERV_CATEG_REPAIR));
        } else {
            orderProduct.setProductId(servProductListResponseDTO.getData().get(0).getProductId());
        }

        orderProduct.setNumber(num);

        List<OrderProductDTO> list = new LinkedList<>();
        list.add(orderProduct);
        zmnOrder.setOrderProductList(list);

        // 京东渠道预付款: 固定塞30元
        zmnOrder.setChannelPrepayAmount(3000 * num); // 价格单位：分
        zmnOrder.setChannelPrepayStatus(PayConsts.PAY_STATUS_DONE);

        // 产品信息记录进日志
        StringBuilder orderInfo = new StringBuilder();
        orderInfo.append("产品：").append(jdOrderDetail.getGoodsName())
                .append("，数量：").append(jdOrderDetail.getGoodsCount())
                .append("，产品编号：").append(jdOrderDetail.getGoodsNo())
                .append("；");
        if (zmnOrder.getOperatorLogRemark() != null) {
            orderInfo.append(zmnOrder.getOperatorLogRemark());
        }
        zmnOrder.setOperatorLogRemark(orderInfo.toString());
    }

}
